package com.apobates.forum.grief.function;

import java.util.function.Supplier;
import org.apache.commons.lang3.tuple.Pair;

/**
 * 取代If/Else命令式表示式
 * 示例:
 *  ImmutablePair<Boolean, Integer> result = EitherBiResult
 *                     .<Boolean, Integer>of(form.isUpdate())
 *                     .thenIf(()->{
 *                         boolean left = platformProtocolService.edit(form.getRecord(), form.toInstance());
 *                         int right = form.getRecord();
 *                         return Pair.of(left, right);
 *                     })
 *                     .orElse(()->{
 *                         Optional<PlatformProtocol> pp = platformProtocolService.create(form.getTitle(), form.getContent(), form.getProtocolTypeEnum());
 *                         boolean left = false; int right=0;
 *                         if(pp.isPresent()) {
 *                             left = true;
 *                             right = pp.get().getId();
 *                         }
 *                         return Pair.of(left, right);
 *                     })
 *                     .get();
 * @author xiaofanku
 * @since 20210124
 * @param <T> 左边/第一个返回值类型
 * @param <U> 右边/第二个返回值类型
 */
public final class EitherPairResult<T,U> {
    private final boolean condition;
    private final Pair<T, U> result;

    private EitherPairResult(boolean condition, Pair<T, U> result) {
        this.condition = condition;
        this.result = result;
    }

    /**
     * 设置条件表达式
     * @param whereExp 条件表达式
     * @param <T,U>
     * @return
     */
    public static <T,U> EitherPairResult<T, U> of(boolean whereExp){
        return new EitherPairResult<>(whereExp, Pair.of(null, null));
    }

    /**
     * 条件表达式为True时执行参数结果
     * @param trueFunctionExp if的执行函数
     * @return
     */
    public EitherPairResult<T, U> thenIf(Supplier<Pair<T, U>> trueFunctionExp) {
        if(condition) {
            Pair<T, U> trueRs = trueFunctionExp.get();
            return new EitherPairResult<>(condition, trueRs);
        }
        return this;
    }

    /**
     * 条件表达式为False时执行参数结果
     * @param falseFunctionExp else的执行函数
     * @return
     */
    public EitherPairResult<T, U> orElse(Supplier<Pair<T, U>> falseFunctionExp){
        if(!condition) {
            Pair<T, U> falseRs = falseFunctionExp.get();
            return new EitherPairResult<>(condition, falseRs);
        }
        return this;
    }

    /**
     * 获取最终的结果
     * @return
     */
    public Pair<T, U> get(){
        return this.result;
    }
}
